package com.zijidelu.luframework.infrastructure.persistence.repository.core.criteria;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zijidelu.luframework.base.model.PO;
import com.zijidelu.luframework.infrastructure.persistence.dao.BaseDAO;
import com.zijidelu.luframework.infrastructure.persistence.repository.core.base.AbstractRepository;
import com.zijidelu.luframework.utils.CastUtil;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * MybatisPlus数据仓库实现类。
 *
 * @author ZIJIDELU
 * @datetime 2025/10/20 12:50
 */
@Getter
public abstract class AbstractPersistenceContext<P extends PO> implements PersistenceContext<P> {
    /**
     * 实体类型。
     */
    protected final Class<P> poClass = CastUtil.cast(ReflectionKit.getSuperClassGenericType(
            this.getClass(),
            AbstractRepository.class, 0)
    );

    /**
     * MybatisPlus Mapper
     */
    @Setter(onMethod_ = {@Autowired})
    private BaseDAO<P> baseMapper;

    @Setter(onMethod_ = {@Autowired})
    private ObjectProvider<IService<P>> mybatisPlusServiceProvider;
    private IService<P> mybatisPlusService;

    public IService<P> getMybatisPlusService() {
        if (mybatisPlusService == null) {
            mybatisPlusService = mybatisPlusServiceProvider.getIfAvailable();
        }
        return mybatisPlusService;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public LambdaQueryWrapper<P> getBaseLambdaQueryWrapper() {
        return new LambdaQueryWrapper<>(this.getPoClass());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public LambdaQueryChainWrapper<P> getBaseLambdaQueryChainWrapper() {
        return new LambdaQueryChainWrapper<>(getBaseMapper(), this.getPoClass());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public QueryWrapper<P> getBaseQueryWrapper() {
        return new QueryWrapper<>(this.getPoClass());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public QueryChainWrapper<P> getBaseQueryChainWrapper() {
        final QueryChainWrapper<P> queryChainWrapper = new QueryChainWrapper<>(getBaseMapper());
        queryChainWrapper.setEntityClass(this.getPoClass());
        return queryChainWrapper;
    }

    @Override
    public UpdateChainWrapper<P> getBaseUpdateChainWrapper() {
        final UpdateChainWrapper<P> updateChainWrapper = new UpdateChainWrapper<>(getBaseMapper());
        updateChainWrapper.setEntityClass(this.getPoClass());
        return updateChainWrapper;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public LambdaUpdateChainWrapper<P> getBaseLambdaUpdateChainWrapper() {
        final LambdaUpdateChainWrapper<P> lambdaUpdateChainWrapper = new LambdaUpdateChainWrapper<>(getBaseMapper());
        lambdaUpdateChainWrapper.setEntityClass(this.getPoClass());
        return lambdaUpdateChainWrapper;
    }

}
